package com.cmc.cloud.cmclink.doc.service.impl.so;

import cn.hutool.core.collection.CollectionUtil;
import com.cmc.cloud.cmclink.doc.api.document.emums.BusinessTypeEnum;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.OperateLogErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.convert.OperateLogConvert;
import com.cmc.cloud.cmclink.doc.entity.OperateLogDO;
import com.cmc.cloud.cmclink.doc.mapper.OperateLogMapper;
import com.cmc.cloud.cmclink.doc.rpcservice.NucTransferService;
import com.cmc.cloud.cmclink.doc.service.so.OperateLogService;
import com.cmc.cloud.cmclink.doc.vo.sovo.operatelog.OperateLogCreateReqVO;
import com.cmc.cloud.cmclink.doc.vo.sovo.operatelog.OperateLogReqVO;
import com.cmc.cloud.cmclink.doc.vo.sovo.operatelog.OperateLogRespVO;
import com.cmc.cloud.cmclink.doc.vo.sovo.operatelog.OperateLogUpdateReqVO;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;
import com.cmes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cmes.platform.system.nuc.dto.AdminUserDto;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * doc_operate_log Service 实现类
 *
 * @author 集运管理员
 */
@Service
@Validated
public class OperateLogServiceImpl implements OperateLogService {

    @Resource
    private OperateLogMapper operateLogMapper;

    @Resource
    private NucTransferService nucTransferService;

    @Override
    public Long createOperateLog(OperateLogCreateReqVO createReqVO) {
        // 插入
        OperateLogDO operateLog = OperateLogConvert.INSTANCE.convert(createReqVO);
        operateLogMapper.insert(operateLog);
        return operateLog.getId();
    }

    @Override
    public void updateOperateLog(OperateLogUpdateReqVO updateReqVO) {
        // 校验存在
        validateOperateLogExists(updateReqVO.getId());
        // 更新
        OperateLogDO updateObj = OperateLogConvert.INSTANCE.convert(updateReqVO);
        operateLogMapper.updateById(updateObj);
    }

    @Override
    public void deleteOperateLog(Long id) {
        // 校验存在
        validateOperateLogExists(id);
        // 删除
        operateLogMapper.deleteById(id);
    }

    private void validateOperateLogExists(Long id) {
        if (operateLogMapper.selectById(id) == null) {
            throw ServiceExceptionUtil.exception(OperateLogErrorCodeConstants.LIMIT_RULE_ITEM_NOT_EXISTS);
        }
    }

    @Override
    public OperateLogDO getOperateLog(Long id) {
        return operateLogMapper.selectById(id);
    }

    @Override
    public List<OperateLogDO> getOperateLogList(Collection<Long> ids) {
        return operateLogMapper.selectBatchIds(ids);
    }


    public List<OperateLogDO>  batchInsert(List<OperateLogReqVO>  operateList, String businessType,
                                          String operateType, String operateTypeSub,
                                          String operateTypeThird, String operateDesc) {
        List<OperateLogDO> logList = new ArrayList<>();
        if(CollectionUtil.isEmpty(operateList)) {
            return logList;
        }
        operateList.forEach(t->{
            OperateLogDO log = new OperateLogDO();
            log.setBusinessType(businessType);
            log.setBusinessId(t.getBusinessId());
            log.setBusinessNo(t.getBusinessNo());
            log.setOperateType(operateType);
            log.setOperateTypeSub(operateTypeSub);
            log.setOperateTypeThird(operateTypeThird);
            log.setOperateDesc(operateDesc);
            logList.add(log);
        });
        operateLogMapper.insertBatch(logList);
        return logList;
    }

    @Override
    public List<OperateLogRespVO> selectByBusinessId(String businessType, Long businessId) {
        if (businessId != null) {
            LambdaQueryWrapperX<OperateLogDO> queryWrapperX = new LambdaQueryWrapperX<OperateLogDO>();
            queryWrapperX.eqIfPresent(OperateLogDO::getBusinessType, businessType);
            queryWrapperX.eqIfPresent(OperateLogDO::getBusinessId, businessId);
            queryWrapperX.orderByAsc(OperateLogDO::getId);
            return OperateLogConvert.INSTANCE.convertList(operateLogMapper.selectList(queryWrapperX));
        }
        return new ArrayList<>();
    }

    @Override
    public List<OperateLogRespVO> selectByBusinessId(String businessType, Long businessId,
        List<String> operateTypeSubs) {
        if (businessId != null) {
            LambdaQueryWrapperX<OperateLogDO> queryWrapperX = new LambdaQueryWrapperX<OperateLogDO>();
            queryWrapperX.eqIfPresent(OperateLogDO::getBusinessType, businessType);
            queryWrapperX.eqIfPresent(OperateLogDO::getBusinessId, businessId);
            queryWrapperX.inIfPresent(OperateLogDO::getOperateTypeSub, operateTypeSubs);
            queryWrapperX.orderByAsc(OperateLogDO::getId);
            List<OperateLogDO> operateLogDos = operateLogMapper.selectList(queryWrapperX);
            List<String> userIds1 = operateLogDos.stream().map(OperateLogDO::getCreator).collect(Collectors.toList());
            List<Long> userIds2 = userIds1.stream().map(Long::valueOf).collect(Collectors.toList());
            List<AdminUserDto> adminUsers = nucTransferService.getUserProfileByIdList(userIds2);
            Map<String, String> userIdToCodeMap = adminUsers.stream()
                .collect(Collectors.toMap(user -> String.valueOf(user.getId()), AdminUserDto::getNickname));
            operateLogDos.forEach(item -> {
                item.setCreator(userIdToCodeMap.getOrDefault(item.getCreator(), item.getCreator()));
                item.setUpdater(userIdToCodeMap.getOrDefault(item.getUpdater(), item.getUpdater()));
            });
            return OperateLogConvert.INSTANCE.convertList(operateLogDos);
        }
        return new ArrayList<>();
    }
}
